﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

// Qt headers
#include <QIcon>
#include <QBrush>
#include <QFont>
#include <QFontMetrics>

// custom headers
#include "ParametersTableModel.h"
#include "ParametersTableSymbols.h"
#include "IParameterDefinition.gcs.h"
#include "TranslatorManager.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h" 
namespace gmepgcs 
{
    ParametersTableModel::ParametersTableModel(QObject *parent) : 
        QAbstractTableModel(parent), 
        m_vParamters()
    {
    }

    ParametersTableModel::~ParametersTableModel()
    {
    }

    int ParametersTableModel::rowCount(const QModelIndex & parent) const
    {
        if (parent.isValid())
        {
            return 0;
        }

        if (m_vParamters.empty())
        {
            return 0;
        }

        return (int)m_vParamters.size();
    }

    int ParametersTableModel::columnCount(const QModelIndex & parent) const
    {
        Q_UNUSED(parent);
        return COL_TOTAL_COUNT;
    }
    
    QVariant ParametersTableModel::data(const QModelIndex & index, int role) const
    {
        if (!index.isValid())
        {
            return QVariant();
        }

        int row = index.row();
        int col = index.column();

        IParameter *parameter = static_cast<IParameter*>(index.internalPointer());
        if (!parameter || !parameter->Definition)
        {
            return QVariant();
        }
        
        // 参数化标签
        if (col == COL_PARAMETER_FLAG) 
        {
            switch (role) {
            case Qt::DisplayRole:
                return parameter->Definition->GetIsInstance() ? QString::fromStdWString(GBMP_TR(L"实")) : QVariant();
            case Qt::TextAlignmentRole:
                return (int)( Qt::AlignLeft | Qt::AlignVCenter);
            case Qt::TextColorRole:
                return QBrush(QColor(0, 177, 209));
            default:
                break;
            }
        }
        // 参数名
        else if (col == COL_PARAMETER_NAME) 
        {
            std::wstring text = parameter->Definition->GetName();
            switch (role) {
            case Qt::DisplayRole:
            case Qt::ToolTipRole:
                return QString::fromStdWString(text);
            case Qt::TextAlignmentRole:
                return (int) Qt::AlignRight | Qt::AlignVCenter;
            case Qt::SizeHintRole:
            {
                if (text.length() > 10)
                {
                    QFont font;
                    font.setFamily("Microsoft YaHei");
                    font.setPixelSize(12);

                    return QSize(136, 8 + QFontMetrics(font).height() * 2 + 8);
                }
                else
                    break;
            }
            default:
                break;
            }
        }
        // 参数值
        else if (col == COL_PARAMETER_VALUE) 
        {
            switch (role) {
            case Qt::DisplayRole:
            case Qt::ToolTipRole:
            {
                QString value = QString::fromStdWString(parameter->GetDisplayValue());
                if (!value.isEmpty() && parameter->Definition->GetUnitSymbol().size() > 0)
                {
                    value += " " + QString::fromStdWString(parameter->Definition->GetUnitSymbol());
                }

                return value;
            }
            case Qt::TextAlignmentRole:
                return (int)Qt::AlignLeft | Qt::AlignVCenter;
            default:
                break;
            }
        }

        return QVariant();
    }

    QVariant ParametersTableModel::headerData(int section, Qt::Orientation orientation, int role) const
    {
        switch (orientation) 
        {
        // 水平 headers
        case Qt::Horizontal:
            // for recording, refer to http://pm.glodon.com/wiki/pages/viewpage.action?pageId=74646727
            if (role == Qt::AccessibleDescriptionRole)
            {
                return QString::fromStdWString(L"column%1").arg(section);
            }

            switch (section) 
            {
            // 参数化标记
            case COL_PARAMETER_FLAG:
                switch (role) 
                {
                case Qt::DisplayRole:
                    return QString::fromStdWString(GBMP_TR(L"是/否实例参数"));
                case Qt::TextAlignmentRole:
                    return (int)Qt::AlignLeft | Qt::AlignVCenter;
                default:
                    break;
                }
            // 参数名
            case COL_PARAMETER_NAME:
                switch (role) 
                {
                case Qt::DisplayRole:
                    return QString::fromStdWString(GBMP_TR(L"参数名"));
                case Qt::TextAlignmentRole:
                    return (int)Qt::AlignRight | Qt::AlignVCenter;
                default:
                    break;
                }
            // 参数值
            case COL_PARAMETER_VALUE:
                switch (role) 
                {
                case Qt::DisplayRole:
                    return QString::fromStdWString(GBMP_TR(L"参数值"));
                case Qt::TextAlignmentRole:
                    return (int)Qt::AlignLeft | Qt::AlignVCenter;
                default:
                    break;
                }
            default:
                break;
            }
            break;
        // 垂直 headers
        case Qt::Vertical:
            // for recording, refer to http://pm.glodon.com/wiki/pages/viewpage.action?pageId=74646727
            if (role == Qt::AccessibleDescriptionRole)
            {
                return QString::fromStdWString(L"row%1").arg(section);
            }
            break;
        default:
            break;
        }


        return QVariant();
    }

    QModelIndex ParametersTableModel::index(int row, int column, const QModelIndex & parent) const
    {
        if (hasIndex(row, column, parent) && row < rowCount() && column < columnCount() && row < m_vParamters.size())
        {
            //IParameter *pParameter = const_cast<IParameter *>(m_vParamters.at(row).get());
            return createIndex(row, column, m_vParamters.at(row).get());
        }

        return QAbstractTableModel::index(row, column, parent);
    }
    
    void ParametersTableModel::PopulateData(std::vector<std::shared_ptr<IParameter>> paramters)
    {
        int oldRowCount = rowCount();
        if (oldRowCount > 0)
        {
            beginRemoveRows(QModelIndex(), 0, oldRowCount - 1);
            removeRows(0, oldRowCount);
            endRemoveRows();
        }
                
        m_vParamters = paramters;
        
        int newRowCount = (int)m_vParamters.size();
        if (newRowCount > 0)
        {
            beginInsertRows(QModelIndex(), 0, newRowCount - 1);
            insertRows(0, newRowCount);
            endInsertRows();
        }

        emit dataChanged(createIndex(0, 0), createIndex(newRowCount - 1, columnCount() - 1));
    }
}
